package com.talent.core.protocol.ocpp;


import com.talent.core.protocol.websocket.handler.TlWsHandler;
import com.talent.core.protocol.websocket.zk.ZkRegister;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.util.internal.logging.Slf4JLoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ClassName：Server
 * @Author: hszhou
 * @Date: 2024/11/15 15:10
 * @Description: 必须描述类做什么事情, 实现什么功能
 */
public class OcppServer {

    private final static Logger logger = LoggerFactory.getLogger(OcppServer.class);

    public static void main(String[] args) throws Exception {

        NioEventLoopGroup work = new NioEventLoopGroup();
        NioEventLoopGroup boss = new NioEventLoopGroup();
        ServerBootstrap bootstrap = new ServerBootstrap();
// 设置Netty使用SLF4J作为日志门面
        InternalLoggerFactory.setDefaultFactory(Slf4JLoggerFactory.INSTANCE);


        bootstrap.group(boss,work)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        //websocket是基于http协议的 所以需要添加http编解码器
                        pipeline.addLast(new HttpServerCodec());
                        //添加对大数据流的支持
                        pipeline.addLast(new ChunkedWriteHandler());
                        //对http消息的聚合FullHttpRequest或FullHttpResponse
                        //之后在netty的编程中 都会使用到此handler
                        pipeline.addLast(new HttpObjectAggregator(1024*64));
                        //================以下适用于支持websocket====================
                        /**
                         * websocket服务器处理协议，用于指定客户端连接的是访问路由
                         * 次handler会帮我处理一些比较负载的繁重的操作
                         * 会处理一些握手操作。
                         * 对于websocket来说 素具都是以frames进行传输，不懂类型的数据类型所对应的frames也是不同的
                         */
                        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
                        pipeline.addLast(new TlWsHandler());
                    }
                });
        int nettyPort=18083;
        ChannelFuture channelFuture = bootstrap.bind(nettyPort).sync();
        logger.info("websocket服务器启动成功");


        //注册当前netty的服务到zookeeper中
        ZkRegister.registerNettyServer("service-list",ZkRegister.getLocalIp(),nettyPort);
        channelFuture.channel().closeFuture().sync();



    }
}
